//
//  QRCodeTool.m
//  BSBDJ
//
//  Created by user on 16/5/24.
//  Copyright © 2016年 Burning. All rights reserved.
//

#import "QRCodeTool.h"
#import <AVFoundation/AVFoundation.h>
@class AVMetadataObjectInternal;
@interface QRCodeTool()<AVCaptureMetadataOutputObjectsDelegate>
//扫描结果block
@property (nonatomic, copy) scanfResult result;
//输出
@property (nonatomic, strong) AVCaptureDeviceInput *input;
//输出
@property (nonatomic, strong) AVCaptureMetadataOutput *output;
//回话
@property (nonatomic, strong) AVCaptureSession *session;
//预览图层
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *avLayer;
//描述
@property (nonatomic, assign) BOOL isDraw;

@property (nonatomic, strong) NSMutableArray *deleteTempLayers;

@end

@implementation QRCodeTool

static QRCodeTool* _instance;
// 单例
+ (instancetype)shareInstance
{
    return [[self alloc] init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
   
    return _instance;
}


-(NSMutableArray *)deleteTempLayers
{
    if (!_deleteTempLayers) {
        _deleteTempLayers = [NSMutableArray array];
    }
    return _deleteTempLayers;
}

// 懒加载输入
- (AVCaptureDeviceInput *)input{
    if (_input == nil) {
        //1.获取摄像头设备
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        //2.设为输入设备
        _input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    }
    return _input;
}
// 懒加载输出
- (AVCaptureMetadataOutput *)output{
    if (_output == nil) {
        // 1. 创建元数据输出处理对象
        _output = [[AVCaptureMetadataOutput alloc]init];
        // 2. 设置元数据输出处理的代理, 来接收输出的数据内容
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    }
    return _output;
}

// 会话
- (AVCaptureSession *)session{
    if (_session == nil) {
        //创建回话 链接输入和输出
        _session = [[AVCaptureSession alloc]init];
        
    }
    return _session;
}
// 预览图层
- (AVCaptureVideoPreviewLayer *)avLayer{
    if (_avLayer == nil) {
        _avLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
    }
    return _avLayer;
}

#pragma mark --------------
#pragma mark 识别二维码
- (NSArray *)detectorQRCode :(UIImage *)image{
    // 1. 创建二维码探测器
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    // 2.探测图片特征
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    NSArray *resultInfo = [detector featuresInImage:ciImage];


    NSMutableArray *strs = [NSMutableArray array];
    
    
    for (CIQRCodeFeature *feature in resultInfo) {
        
        [strs addObject:[feature messageString]];
    }
   
    return strs;
}


#pragma mark --------------
#pragma mark 二维码扫描接口
- (void)scanfQRCodeInView :(UIView *)view isDraw :(BOOL)isDraw :(scanfResult )resultBlock{
    _result = resultBlock;
    self.isDraw = isDraw;
    
    //1.添加输入和输出
    if([self.session canAddInput:self.input] && [self.session canAddOutput:self.output]){
        [self.session addInput:self.input];
        [self.session addOutput:self.output];
        [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
    }else{
        resultBlock(nil);
        return;
    }
    
    // 添加预览图层
    if (![view.layer.sublayers containsObject:self.avLayer])
    {
        self.avLayer.frame = view.layer.bounds;
        [view.layer insertSublayer:self.avLayer atIndex:0];
    }
    
    // 5. 启动会话
    [self.session startRunning];
    
}

- (void)setInterestRect :(CGRect)rect{
    CGRect screenRect = [UIScreen mainScreen].bounds;
    CGFloat x = rect.origin.x / screenRect.size.width;
    CGFloat y = rect.origin.y / screenRect.size.height;
    CGFloat w = rect.size.width / screenRect.size.width;
    CGFloat h = rect.size.height / screenRect.size.height;
    _output.rectOfInterest = CGRectMake(x, y, w, h);
}
// 停止扫描
- (void)stopScan
{
    [self.session stopRunning];
}


#pragma mark --------------
#pragma mark 实现代理方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    
    if (self.isDraw){
        [self removeShapLayers];
    }
    
    NSMutableArray *resultStrs = [NSMutableArray array];
    for (AVMetadataMachineReadableCodeObject *obj in metadataObjects)
    {
        [resultStrs addObject:obj.stringValue];
        
        if (self.isDraw) {
            // obj 中的四个角, 是没有转换后的角, 需要我们使用预览图层转换
            AVMetadataMachineReadableCodeObject *tempObj = (AVMetadataMachineReadableCodeObject *)[self.avLayer transformedMetadataObjectForMetadataObject:obj];
            [self addShapLayers:tempObj];
            
        }
        
    }
    if (self.result)  self.result(resultStrs);

}


// 添加二维码边框图层
- (void)addShapLayers:(AVMetadataMachineReadableCodeObject *)transformObj
{
    // 绘制边框
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.strokeColor = [UIColor redColor].CGColor;
    layer.lineWidth = 6;
    layer.fillColor = [UIColor clearColor].CGColor;
    
    // 创建一个贝塞尔曲线
    UIBezierPath *path = [[UIBezierPath alloc] init];
    
    
    int index = 0;
    for (NSDictionary *pointDic in transformObj.corners)
    {
        CFDictionaryRef dic = (__bridge CFDictionaryRef)(pointDic);
        CGPoint point = CGPointZero;
        CGPointMakeWithDictionaryRepresentation(dic, &point);
        if (index == 0) {
            [path moveToPoint:point];
        }else
        {
            [path addLineToPoint:point];
        }
        index ++;
        
    }
    [path closePath];
    layer.path = path.CGPath;
    [self.avLayer addSublayer:layer];
    [self.deleteTempLayers addObject:layer];
}
// 移除二维码边框图层
- (void)removeShapLayers
{
    // 移除图层
    for (CALayer *layer in self.deleteTempLayers) {
        [layer removeFromSuperlayer];
    }
    
    [self.deleteTempLayers removeAllObjects];
    
}
@end
